import { HTML_TAG_STATUS } from "../constant";
import HNode from "./HNode";

/**
 * 修改 ASTNode 对象， 将其改为在 HNode 节点的基础上进行扩展，而不是采用新的结构
 * 因为创建新的对象开销很大，不如直接在其上进行修改
 * 至于单独创建这个类，是为了给最后生成的对象一个结构参考
 */

export default class ASTNode {

    /**
     * 创建标识AST节点的内存对象
     * @param {String} tag ast标签的名称 （举例：div，a, h1, h2）
     * @param {Number} type html标签的类型 (举例：Node HTML节点, Comment HTML注释, Text HTML中的文本内容)
     * @param {String} status html标签的状态，是开口标签<div>，闭口标签</div>，还是独立闭合标签 <br />
     * @param {Array<{key:String, value:String}>} attrsList html标签的属性数组
     * @param {Number} start 节点字符串对应的开始位置
     * @param {ASTNode} parent ast节点的父节点
     * @param {Array<ASTNode>} children ast节点的孩子节点数组
     * @param {String} textContent 节点为 Text 节点时，节点的文本值
     */
    constructor (tag,
                 type,
                 status,
                 attrsList,
                 start,
                 parent,
                 children,
                 textContent) {

        // ================ HNode 原属性 =========================
        this.tag = tag;
        this.type = type;
        this.status = status;
        this.attrsList = attrsList ? attrsList.slice(0) : [];
        this.start = start;
        this.parent = parent;
        this.children = children;
        this.textContent = textContent;

        // ================ ASTNode 新增加属性 ===================

        // 属性 与 事件
        // List
        this.staticAttrList = new Array();
        this.dynamicAttrList = new Array();
        this.staticEventList = new Array();
        this.dynamicEventList = new Array();
        // Map
        this.staticAttrMap = new Map();
        this.dynamicAttrMap = new Map();
        this.staticEventMap = new Map();
        this.dynamicEventMap = new Map();

        // 用于标记 该 ast 节点语法处理是否结束
        this.elementProcessed = false;
        // 是否在 AST 处理的过程中被标记需要将该节点删除
        this.needDelete = false;
        // 动态节点标记
        this.isDynamic = false;
        // 各种 指令情况标记
        this.conditionBitMap = {
            pre: false,

            slotDeclaration: false,
            slotImplement: false,

            once: false,
            for: false,
            key: false,
            show: false,
            if: false,
            elseIf: false,
            else: false,

            component: false,
        };

        // 各种 指令未处理的字符串值
        this.conditionStrValueMap = {};
        // this.conditionStrValueMap = {
        //     pre: "",

        //     slotDeclaration: {
        //         name: "",
        //     },
        //     slotImplement: {
        //         name: "",
        //         scope: "",
        //     },

        //     once: "",
        //     for: "",
        //     key: "",
        //     if: "",
        //     show: "",
        //     elseIf: "",
        //     else: "",
        //     // component 无信息需要单独记录，大部分信息在 HtmlParser 都已经处理了, 可以直接拿出来用
        // };

        // 各个动态指令对应的指令信息存储结构
        this.conditionMessage = {};
        // this.conditionMessage = {
        //     pre: Boolean,

        //     slotDeclaration: {
        //         name: String,
        //     },
        //     slotImplement: {
        //         name: String,
        //         scope: String,
        //     },

        //     once: Boolean,
        //     for: {
        //         iter1: String,
        //         iter2: String,
        //         alias: String,
        //         index: String,
        //         opt: String,
        //         obj: String,
        //         number: Number,
        //     },
        //     key: {
        //         exp: String,
        //     }
        //     show: {
        //         exp: String,
        //         block: ASTNode,
        //     },
        //     if: [{
        //         exp: String,
        //         block: ASTNode,
        //     }, {
        //         exp: String,
        //         block: ASTNode,
        //     }],
        //     component: {
        //         componentName: String,
        //         // ASTNode []
        //         暂时不需要实现插槽
        //         slotImplementMap: {
        //              name: astNode,
        //              default: [astNode, astNode]
        //         },
        //     },

        // }

        // Codegen 层使用的 语法处理标记 （若处理了该语法，会将对应语法标记为 true）
        this.processedBitMap = {
            pre: false,

            slotDeclaration: false,
            slotImplement: false,

            once: false,
            for: false,
            key: false,
            show: false,
            if: false,

            component: false,
        };
        // Codegen 层使用的 代码生成标记 （若已生成了代码，会将该标记记为 true）
        this.generated = false;

    }

}
